#include "server.h"

void leech(struct tracker t, struct multiString s)
{
   trackerWrite(t, (char*)"LEECH :D\n");
}

void seed(struct tracker t, struct multiString s)
{
   trackerWrite(t, (char*)"SEED :D\n");
   if(s.length == 2)
   {
      if(!strcmp(s.s[1],"PING"))
      {
         // LOG PING
      }
   }
   if(s.length == 3)
   {
      if(!strcmp(s.s[1],"REQUEST"))
      {
         printf("%s\n",s.s[1]);
         int numPages = cast(s.s[2]);  // CHANGE TO LEXICAL_CAST FUNCTION
         printf("REQUEST FOR %d PAGES\n",numPages);
      }
   }
}

void *servePage(struct tracker t)
{
   char buffer[1024];
   while(1)
   {
      trackerRead(t, buffer);
      struct multiString temp;
      split(buffer, ' ', &temp);
      if(strcmp(temp.s[0], "SEED") == 0)
      {
         seed(t, temp);
      }
      else if(strcmp(temp.s[0], "LEECH") == 0)
      {
         leech(t, temp);
      }
      else
      {
         trackerWrite(t, (char*)"UNKNOWN COMMAND\n");
      }
   }
   close(t.sockfd);
   return 0;
}

void tracker(FILE *out)
{
   struct sockaddr_in addr, client;
   socklen_t clilen;
   int sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if(sockfd == -1)
   {
      printf("ERROR: Socket creation failed: %d\n", errno);
      fprintf(out, "ERROR: Socket creation failed: %d\n", errno);
      exit(0);
   }

   bzero((char*)&addr, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = INADDR_ANY;
   addr.sin_port = htons(8080);

   if(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
   {
      printf("ERROR: Bind failed: %d\n", errno);
      fprintf(out, "ERROR: Bind failed: %d\n", errno);
      exit(0);
   }

   if(listen(sockfd, 0) != 0)
   {
      printf("ERROR: Listen failed: %d\n", errno);
      fprintf(out, "ERROR: Listen failed: %d\n", errno);
      exit(0);
   }

   struct tracker track;
   clilen = sizeof(client);
   track.sockfd = accept(sockfd, (struct sockaddr *)&client, &clilen);
   track.out = out;
   if(track.sockfd < 0)
   {
      printf("ERROR: Accept failed: %d\n", errno);
      fprintf(out, "ERROR: Accept failed: %d\n", errno);
      exit(0);
   }

   servePage(track);
}

void trackerRead(struct tracker t, char *buffer)
{
   bzero(buffer, 1024);
   if(read(t.sockfd, buffer, 1023) < 0)
   {
      printf("ERROR: Read failed: %d\n", errno);
      fprintf(t.out, "ERROR: Read failed: %d\n", errno);
   }
}

void trackerWrite(struct tracker t, char *buffer)
{
   if(write(t.sockfd, buffer, strlen(buffer)) < 0)
   {
      printf("ERROR: Read failed: %d\n", errno);
      fprintf(t.out, "ERROR: Write failed: %d\n", errno);
   }
}



